package com.example.spidertp.core.service.impl;

import com.example.spidertp.config.SpiderThreadPoolConfig;
import com.example.spidertp.core.SpiderThreadPool;
import com.example.spidertp.core.SpiderThreadPoolFactory;
import com.example.spidertp.core.model.enums.TpLifecycleTypeEnum;
import com.example.spidertp.core.model.vo.SpiderThreadPoolArgsVo;
import com.example.spidertp.core.model.vo.SpiderThreadPoolLivingStateVo;
import com.example.spidertp.core.service.SpiderTPService;
import com.example.spidertp.core.service.TpLifecycleService;
import com.example.spidertp.exception.BusinessException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author xiong.bo
 * @version 1.0
 * @date 2022/9/24 10:43 上午
 */

@Service
public class SpiderTPServiceImpl implements SpiderTPService {

    @Autowired
    private SpiderThreadPoolConfig poolConfig;

    @Autowired
    private TpLifecycleService tpLifecycleService;

    @Override
    public List<SpiderThreadPoolLivingStateVo> selectList() {

        List<SpiderThreadPoolLivingStateVo> result = new ArrayList<>();
        Map<String, SpiderThreadPool> poolMap = SpiderThreadPoolFactory.getPoolMap();
        if (ObjectUtils.isEmpty(poolMap)) {
            return result;
        }
        Set<Map.Entry<String, SpiderThreadPool>> entries = poolMap.entrySet();
        for (Map.Entry<String, SpiderThreadPool> s : entries) {
            String key = s.getKey();
            SpiderThreadPool value = s.getValue();
            SpiderThreadPoolLivingStateVo vo = new SpiderThreadPoolLivingStateVo();
            vo.setPoolName(key);
            BeanUtils.copyProperties(value, vo);
            vo.setKeepAliveTime(value.getKeepAliveTime(TimeUnit.SECONDS));
            vo.setUnit(TimeUnit.SECONDS);
            vo.setWorkQueueSize(value.getQueue().size());
            result.add(vo);
        }
        return result;
    }

    @Override
    public SpiderThreadPoolArgsVo createSpiderTp(String poolName) {

        SpiderThreadPool threadPool = SpiderThreadPoolFactory.createThreadPool(poolName,
                poolConfig.getCorePoolSize(),
                poolConfig.getMaxPoolSize(),
                poolConfig.getKeepAliveTime(),
                poolConfig.getQueueCapacity());
        SpiderThreadPoolArgsVo result = new SpiderThreadPoolArgsVo();
        result.setCorePoolSize(threadPool.getCorePoolSize());
        result.setMaximumPoolSize(threadPool.getMaximumPoolSize());
        result.setKeepAliveTime(threadPool.getKeepAliveTime(TimeUnit.SECONDS));
        result.setUnit(TimeUnit.SECONDS);
        result.setWorkQueue(threadPool.getQueue());
        //记录创建线程池
        tpLifecycleService.createTpRecord(poolName, threadPool, TpLifecycleTypeEnum.CREATE);
        return result;
    }

    @Override
    public boolean removeSpiderTp(String poolName) {
        SpiderThreadPool threadPool = SpiderThreadPoolFactory.getThreadPool(poolName);
        if (null == threadPool) {
            throw new BusinessException("线程池[" + poolName + "]不存在");
        }
        if (threadPool.getActiveCount() > 0) {
            throw new BusinessException("线程池：" + poolName + ",处于活动状态，不能销毁");
        }
        threadPool.shutdown();
        //记录销毁线程池
        tpLifecycleService.createTpRecord(poolName, threadPool, TpLifecycleTypeEnum.SHUTDOWN);
        return true;
    }
}
